import rsa
import sys
from tkinter import *
import tkinter.messagebox
import binascii

key_flag = False

# 生成公私密钥对
def rsa_key():
    global pub, priv, key_flag
    # 判断密钥位数输入是否为全数字类型，如果全是就获取公私密钥，否则弹框警告。
    if k.get().strip().isdigit() == True:
        key = int(k.get().strip())
        pub, priv = rsa.newkeys(key)
        key_flag = True
        msg = "公钥：" + str(pub) + '\n' + '私钥：' + str(priv)
        tkinter.messagebox.showinfo(title='公私密钥', message=msg)
    else:
        key_flag = False
        tkinter.messagebox.showwarning(title='警告！', message='请输入由数字组成的密钥！')



def rsa_mode(pwd, mode):

    # 选择Rsa工作模式
    if mode == True:
        # 公钥加密
        talk = pwd.encode('utf-8')
        cryto_info = rsa.encrypt(talk, pub)
        out_hex = binascii.b2a_hex(cryto_info)
        out_str = out_hex.decode()
        print(out_str)
        r.set(str(out_str))
        return str(out_str)
    else:
        # 私钥解密
        out_hex = str.encode(pwd)
        out_bytes = binascii.a2b_hex(out_hex)
        talk_real = rsa.decrypt(out_bytes, priv).decode()
        r.set(str(talk_real))
        return str(talk_real)

# 定义加密按钮触发功能函数
def encryption():
    # 获取原文输入框内容
    pwd = u.get()
    if key_flag == False:
        tkinter.messagebox.showwarning(title='警告！', message='请输入需要生成的密钥位数！')
    elif len(pwd) == 0:
        tkinter.messagebox.showwarning(title='警告！', message='请输入需要加密的内容！')
    else:
        tkinter.messagebox.showinfo(title='加密结果', message=(rsa_mode(pwd, True)))


# 定义解密按钮触发功能函数
def decryption():
    # 获取原文输入框内容
    pwd = u.get()
    if key_flag == False:
        tkinter.messagebox.showwarning(title='警告！', message='请输入需要生成的密钥位数！')
    elif len(pwd) == 0:
        tkinter.messagebox.showwarning(title='警告！', message='请输入需要解密的内容！')
    else:
        tkinter.messagebox.showinfo(title='加密结果', message=(rsa_mode(pwd, False)))

# 实例化object，建立窗口window
windows = Tk()

# 给窗口的可视化起名字
windows.title("rsa")

# 使用框架（Frame）控件在屏幕上显示一个矩形区域，用来作为容器。
frame = Frame(windows)

# padx和pady用于设置框架的外部填充显示，ipadx和ipady用于设置框架的内部显示。
frame.pack(padx=8, pady=8, ipadx=4, ipady=0)

'''
界面设置：
    1、原文输入框；
    2、密钥输入框；
    3、加密解密按钮。
'''

lab_key = Label(frame, text="密钥位数:")
lab_key.grid(row=0, column=0, padx=5, pady=5, sticky=W)

k = StringVar()
ent_key = Entry(frame, show='*', textvariable=k)
ent_key.grid(row=0, column=1, sticky='ew', columnspan=2)

lab_pwd = Label(frame, text="输入文本:")
lab_pwd.grid(row=1, column=0, padx=5, pady=5, sticky=W)

u = StringVar()
ent_pwd = Entry(frame, textvariable=u)
ent_pwd.grid(row=1, column=1, sticky='ew', columnspan=2)

lab_pwd = Label(frame, text="输出文本:")
lab_pwd.grid(row=2, column=0, padx=5, pady=5, sticky=W)

r = StringVar()
ent_key = Entry(frame, textvariable=r)
ent_key.grid(row=2, column=1, sticky='ew', columnspan=2)

button_encryption = Button(frame, text="生成密钥", command=rsa_key, default='active')
button_encryption.grid(row=3, column=0, padx=5, pady=5)

button_encryption = Button(frame, text="加密", command=encryption, default='active')
button_encryption.grid(row=3, column=1, padx=5, pady=5)

button_decryption = Button(frame, text="解密", command=decryption, default='active')
button_decryption.grid(row=3, column=2, padx=5, pady=5)


# 居中显示窗口
windows.update_idletasks()
x = (windows.winfo_screenwidth() - windows.winfo_reqwidth()) / 2
y = (windows.winfo_screenheight() - windows.winfo_reqheight()) / 2
windows.geometry("+%d+%d" % (x, y))

# 禁止拉伸窗口
windows.resizable(0, 0)

# 主窗口循环显示
windows.mainloop()